﻿using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using BearUtil.Hidden;
using Sirenix.OdinInspector;
using UnityEngine;
using XNode;

namespace BearUtil
{
    public enum TalkPosition
    {
        Left = 1,
        Right = 2
    }

    public enum BubbleType
    {
        Default = 1,
        Thinking = 2
    }

    public enum SceneType
    {
        None = -1,    
        Default = 1,
        Thinking = 2
    }

    [CreateNodeMenu(menuName: "自定义节点/台词节点"), Title("台词节点"), NodeWidth(280)]
    public class TalkNode : BearNode
    {
        [HideInInspector] public int type = 1;

        [SerializeField, HideLabel, ValueDropdown("GetActors"), OnValueChanged("actorChanged")]
        public ActorData actor;

        [Sirenix.OdinInspector.ReadOnly]
        [LabelText("角色"), PreviewField(55, ObjectFieldAlignment.Center), ShowIf("actor")]
        public Texture header;

        /// <summary>
        /// 立绘位置
        /// </summary>
        [LabelText("立绘位置"), ShowIf("actor")] public TalkPosition portrait_direction;

        [LabelText("立绘图标(Spine 动画名)"), ValueDropdown("GetPortraitIcon", DropdownWidth = 300), ShowIf("actor")]
        public string icon_portrait;

        [LabelText("展示图片"),] public string[] show_pic;
        [LabelText("展示背景"),] public string[] show_bg;
        /// <summary>
        /// 角色首选名称
        /// </summary>
        [LabelText("角色首选名称"), ValueDropdown("GetRoleName", DropdownWidth = 300), ShowIf("actor")]
        public string role_name;

        [LabelText("对话气泡样式")] public BubbleType lines_bubble = BubbleType.Default;

        [LabelText("场景气泡样式")] public SceneType scene_bubble = SceneType.Default;

        [LabelText("字体速度")] public float FontSpeed = 30;

        [LabelText("音频"), ValueDropdown("getAudioClip", DropdownWidth = 300)]
        public string VoiceClip;

        [HideLabel]
        // public AudioPlayData audioData = new AudioPlayData();
        private List<string> getAudioClip()
        {
            if (actor == null)
                return null;
            var clips = AudioCtrl.Instance.Clips;
            List<string> specialClips = new List<string>();
            List<VoiceType> r = new List<VoiceType>();
            var voices = typeof(VoiceType).GetEnumValues();    
            for (int i = 0; i < voices.Length; i++)
            {
                var v = voices.GetValue(i);
                if (((int) actor.voice_type & (int) v) > 0)
                {
                    for (var j = 0; j < clips.Count; j++)
                    {
                        if (!Regex.Match(@$"{clips[j].name}", v.ToString()).Value.Equals(""))
                            specialClips.Add(clips[j].name);
                    }
                }
            }
            
            specialClips.Insert(0, "null");
            return specialClips;
        }


        [LabelText("是否显示台词在场景上"), LabelWidth(130)]
        public bool showOnScene = false;

        [LabelText("文本 id"), ValueDropdown("GetLineKey", DropdownWidth = 300), OnValueChanged("switchContent")]
        public string lines;

        [HideLabel, TextArea, Sirenix.OdinInspector.ReadOnly]
        public string content;

        // 切换角色数据后
        private void actorChanged(ActorData data)
        {
            if (data == null)
                return;
            if (data.Icon == null)
                return;

            header = data.Icon;
        }

        private string[] GetPortraitIcon()
        {
            if (actor == null)
                return null;

            return actor.icon_portrait;
        }

        /// <summary>
        /// 从 series 获取登场角色
        /// </summary>
        /// <returns></returns>
        private ActorData[] GetActors()
        {
            var storyGraph = ((graph as DialogGraph)?.owner.graph as StoryGraph);
            if (storyGraph != null)
            {
                var series = StoriesSetting.Instance.FindSeriesByStoryGraph(storyGraph);
                return series.Actors.ToArray();
            }

            return new ActorData[0];
        }

        private string[] GetRoleName()
        {
            if (actor == null)
                return null;

            return actor.role_names;
        }

        private List<string> GetLineKey()
        {
            return LanguageCtrl.Instance.Langs;
        }

        private void switchContent(string lineKey)
        {
            // switch content
            content = LanguageCtrl.Instance.GetLineContent(lineKey);
        }
    }
}